#define CHAT_WIDGETS_CAPACITY	12

enum enum_chat_widgets {
	BOX_0 = 0,
	BOX_1,
	BOX_2,
	BOX_3,
	BUTTON_0,
	BUTTON_1,
	BUTTON_2,
	LABEL,
	SCROLL_0,
	SCROLL_1,
	TEXTVIEW_0,
	TEXTVIEW_1
};

/**
** @struct Chat
**	@var address is the address struct of the chat
**	@var page is the page index on the notebook
** @var counter_posts is a integer
** @var counter_recvs is a integer
**	@var port used by the chat
**	@var size is the address struct size of the chat
**	@var socket is the socket descriptor of the chat
**	@var thread is a thread to execute the connection of the chat
**	@var username is a string that represents the username of the chat
**	@var widgets the collection of widgets used on a notebook
*/

typedef struct {
	gchar username[USERNAME_CAPACITY];
	gint counter_posts;
	gint counter_recvs;
	gint page;
	gint size;
	gint socket;
	GtkWidget *widgets[CHAT_WIDGETS_CAPACITY];
	pthread_t thread;
	struct sockaddr_in sck_addr;
} Chat;

/**
** @fn init_chat
** @brief initializes the a Chat
** @param chat is a pointer of Chat
** @param name is a string
** @param address is a string
** @param port is a integer 
*/

void init_chat(Chat *chat, char *username, struct sockaddr_in *sck_addr) {
	strcpy(chat->username, username);
	chat->counter_posts = 0;
	chat->counter_recvs = 0;	
	chat->page = -1;
	chat->size = sizeof(struct sockaddr_in);
	memset(&chat->sck_addr, 0, chat->size);
	if(sck_addr != NULL)	{
		chat->sck_addr.sin_family = sck_addr->sin_family;
		chat->sck_addr.sin_port = sck_addr->sin_port;
		chat->sck_addr.sin_addr.s_addr = sck_addr->sin_addr.s_addr;
	}
}

/**
** @fn new_chat
** @brief 
** @param name is a string
** @param address is a string
** @param port is a integer 
*/

static Chat * new_chat(char *username, struct sockaddr_in *address) {
	Chat *ch = (Chat *) malloc(sizeof(Chat));
	init_chat(ch, username, address);
	return ch;
}

/**
** @fn compare_address
** @brief compares the adress from two chats
** @param ch1 is a pointer
** @param ch2 is a pointer
*/

gint compare_address(gconstpointer ch1, gconstpointer ch2) {
	gchar addr1[INET_ADDRSTRLEN], addr2[INET_ADDRSTRLEN]; 
	inet_ntop(AF_INET, &((Chat *) ch1)->sck_addr.sin_addr, addr1, INET_ADDRSTRLEN);
	inet_ntop(AF_INET, &((Chat *) ch2)->sck_addr.sin_addr, addr2, INET_ADDRSTRLEN);
	return (gint) strcmp(addr1, addr2);
}

/**
** @fn config_chat_widgets
** @brief configures the widgets of a chat
** @param chat is a pointer of reference for a chat
*/

void config_chat_widgets(Chat *chat) {
	gtk_button_set_image(GTK_BUTTON(chat->widgets[BUTTON_0]), gtk_image_new_from_icon_name("dialog-close", GTK_ICON_SIZE_INVALID));
	gtk_text_view_set_editable(GTK_TEXT_VIEW(chat->widgets[TEXTVIEW_0]), FALSE);
	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(chat->widgets[TEXTVIEW_0]), GTK_WRAP_WORD_CHAR);
	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(chat->widgets[TEXTVIEW_0]), 3);
	gtk_text_view_set_right_margin(GTK_TEXT_VIEW(chat->widgets[TEXTVIEW_0]), 3);
	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(chat->widgets[TEXTVIEW_1]), GTK_WRAP_WORD_CHAR);
	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(chat->widgets[TEXTVIEW_1]), 3);
	gtk_text_view_set_right_margin(GTK_TEXT_VIEW(chat->widgets[TEXTVIEW_1]), 3);
	gtk_container_set_border_width(GTK_CONTAINER(chat->widgets[BOX_1]), 3);
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(chat->widgets[SCROLL_0]), GTK_SHADOW_IN);
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(chat->widgets[SCROLL_1]), GTK_SHADOW_IN);
	gtk_widget_set_size_request(chat->widgets[SCROLL_0], 400, -1);
	gtk_container_add(GTK_CONTAINER(chat->widgets[SCROLL_0]), chat->widgets[TEXTVIEW_0]);
	gtk_container_add(GTK_CONTAINER(chat->widgets[SCROLL_1]), chat->widgets[TEXTVIEW_1]);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_3]), chat->widgets[BUTTON_1], FALSE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_3]), chat->widgets[BUTTON_2], FALSE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_2]), chat->widgets[SCROLL_1], FALSE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_2]), chat->widgets[BOX_3], FALSE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_1]), chat->widgets[SCROLL_0], FALSE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_1]), chat->widgets[BOX_2], FALSE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_0]), chat->widgets[LABEL], FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(chat->widgets[BOX_0]), chat->widgets[BUTTON_0], FALSE, FALSE, 0);
	gtk_box_set_child_packing(GTK_BOX(chat->widgets[BOX_1]), chat->widgets[SCROLL_0], TRUE, TRUE, 0, GTK_PACK_START);
	gtk_box_set_child_packing(GTK_BOX(chat->widgets[BOX_2]), chat->widgets[SCROLL_1], TRUE, TRUE, 0, GTK_PACK_START);
	gtk_box_set_child_packing(GTK_BOX(chat->widgets[BOX_3]), chat->widgets[BUTTON_1], FALSE, TRUE, 0, GTK_PACK_START);
	gtk_box_set_child_packing(GTK_BOX(chat->widgets[BOX_3]), chat->widgets[BUTTON_2], FALSE, TRUE, 0, GTK_PACK_START);
}

/**
** @fn create_chat_widgets
** @brief creates the widgets of a chat
** @param chat is a pointer of reference for a chat
*/

void create_chat_widgets(Chat *chat) {
	chat->widgets[BOX_0] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
	chat->widgets[BOX_1] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
	chat->widgets[BOX_2] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
	chat->widgets[BOX_3] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
	chat->widgets[BUTTON_0] = gtk_button_new( );
	chat->widgets[BUTTON_1] = gtk_button_new_with_label(BUTTON_SEND);
	chat->widgets[BUTTON_2] = gtk_button_new_with_label(BUTTON_CLEAR);
	chat->widgets[LABEL] = gtk_label_new(chat->username);
	chat->widgets[SCROLL_0] = gtk_scrolled_window_new(NULL, NULL);
	chat->widgets[SCROLL_1] = gtk_scrolled_window_new(NULL, NULL);
	chat->widgets[TEXTVIEW_0] = gtk_text_view_new( );
	chat->widgets[TEXTVIEW_1] = gtk_text_view_new( );
	config_chat_widgets(chat);
	int i = 0;	
	for(i = 0; i < CHAT_WIDGETS_CAPACITY; ++i)
		gtk_widget_show(chat->widgets[i]);
}
